package com.eagle.springbootservlet;


import com.eagle.springservlet.AsyncServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.CharacterEncodingFilter;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import java.util.EnumSet;

/**
 * Spring Boot Servlet 引导类
 *
 * @author 小马哥
 * @since 2018/6/5
 */
@EnableAutoConfiguration
//把spring-servlet中的AsyncServlet引导过来，相当于注册了/async-servlet
@ServletComponentScan(basePackages = "com.eagle.springservlet")
public class SpringBootServletBootstrap {

    public static void main(String[] args) {

    	SpringApplication.run(SpringBootServletBootstrap.class, args);
    }

    //注册指定的servlet，类似于spring-servlet中的@WebServlet的实现
	//这里AsyncServlet注册了/
    @Bean
	//这里和DispatcherServlet的mapping冲突，因此需要调整它的优先级，这里覆盖了DispatcherServlet的注册
	//可以断点在DispatcherServlet#doDispatch求证
	//如果servlet重名，则会先注册先进来的bean,因此这里要给AsyncServlet起别名MyAsyncServlet
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ServletRegistrationBean asyncServletServletRegistrationBean(){
        ServletRegistrationBean registrationBean =  new ServletRegistrationBean(new AsyncServlet(),"/");
        registrationBean.setName("MyAsyncServlet");
        return registrationBean;
    }

	//ServletContextInitializer是一个典型的->实现
	//springboot不支持ServletContainerInitializer（参考DefaultAnnotationConfigDispatcherServletInitializer）
	//如果要实现类似spring-servlet的ServletContainerInitializerspringboot
	// springboot需要重新实现ServletContextInitializer接口,例如这里，就添加了一个过滤器，实现了字符编码
    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
        	//重新实现了一个CharacterEncodingFilter
            CharacterEncodingFilter filter = new CharacterEncodingFilter();
            FilterRegistration.Dynamic registration = servletContext.addFilter("filter", filter);
            registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/");
        };
    }
}
